home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / TCL1 / MIDI_MAN / CMIDITIM.C < prev    next >
Text File  |  1992-03-07  |  8KB  |  252 lines

  1. //--- CMIDITimePort.c ------------------------------------------------------------------
  2. // Copyright ⌐ Paul Ferguson, 1990, 1991, 1992.  All rights reserved.
  3. //
  4. // Description:
  5. //    CMIDITimePort.c defines a MIDI Manager time port object.
  6. //
  7. //    For use with THINK C 5.0, the accompanying THINK Class Library (TCL), and MIDI
  8. //    Manager 2.0. Refer to the accompanying Microsoft Word document for complete
  9. //    details about MIDI Manager objects.
  10. //
  11. //    If you have comments or questions about this code, you can reach me on
  12. //    CompuServe at 70441,3055.
  13. //
  14. //--------------------------------------------------------------------------------------
  15. //---- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE ----
  16. //--------------------------------------------------------------------------------------
  17. //    If you are not familiar with programming the Apple MIDI Manager, refer to the
  18. //    "MIDI Management Tools" Version 2.0, available from APDA.  You MUST have the
  19. //    software (MIDI.H and the library) from this package in order to use these objects.
  20. //    It will not work without this.
  21. //--------------------------------------------------------------------------------------
  22. //    REVISION HISTORY:
  23. //        August ??, 1990            - Original release (1.0).
  24. //        November 5, 1990        - Added checks for midiMgrVer to most methods.
  25. //        August 1991                - updated for THINK C 5.0 as version 2.0
  26. //--------------------------------------------------------------------------------------
  27.  
  28. #include "CMIDITimePort.h"                    // This code's header file
  29. #include <CApplication.h>
  30.  
  31. extern    CApplication    *gApplication;        // Used in SetConnection
  32. extern    OSType            gSignature;            // Used to register client
  33. #define noClient        '    '                // The UnClient
  34.  
  35. extern CMIDIClient * gMIDIClient;
  36.  
  37.  
  38. //--- CMIDITimePort methods ------------------------------------------
  39. // Methods for a MIDI Manager time port.
  40. // Superclass        CMIDIPort
  41. // Subclasses        None
  42. //--------------------------------------------------------------------
  43.  
  44. OSErr CMIDITimePort::IMIDITimePort(StringPtr    theName,
  45.                                    OSType        thePortID,
  46.                                    Boolean        theVisibleFlag,
  47.                                    short        theFormat)
  48. {
  49.     MIDIPortParams                    portParams;
  50.     register MIDIPortParams *        portPPtr = &portParams;
  51.     OSErr                            theResult;
  52.  
  53.     portPPtr->portID                = thePortID;
  54.     portPPtr->portType                = midiPortTypeTime;
  55.     if (theVisibleFlag == FALSE)
  56.     {
  57.         if (itsVersion >= 0x0200)
  58.             portPPtr->portType        |= midiPortInvisible;        // Use 2.0 preferred syntax
  59.         else
  60.             portPPtr->portType        = midiPortTypeTimeInv;        // Use 1.x syntax
  61.     }
  62.     portPPtr->timeBase                = 0;
  63.     portPPtr->offsetTime            = 0;
  64.     portPPtr->readHook                = (Ptr) 0;
  65.     portPPtr->refCon                = 0;
  66.     portPPtr->initClock.sync        = midiInternalSync;        // Always start out internal
  67.     portPPtr->initClock.curTime        = 0;
  68.     portPPtr->initClock.format        = theFormat;
  69.     BlockMove(theName, portPPtr->name, theName[0]+1);
  70.  
  71.     theResult = IMIDIPort(portPPtr, 0);
  72.     if (theResult == noErr)
  73.     {
  74.         UpdateSync();        // Check for time base connections
  75.     }
  76.  
  77.     return (theResult);
  78. }
  79.  
  80. //--- CMIDITimePort::LoadPatches --------------------------------------------
  81. // Load any time patches, and make connections.
  82. //---------------------------------------------------------------------------
  83.  
  84. OSErr CMIDITimePort::LoadPatches(ResType theResType, short theResID)
  85. {
  86.     OSErr                theErr = noErr;
  87.     MIDIPortInfoHdl        rezPortInfoH, ourPortInfoH;
  88.     short                i;
  89.     Str255                theName;
  90.  
  91.     if ( itsVersion == 0 )        // Couldn╒t open the MIDI Manager for some reason
  92.         return (ErrNoMIDI);
  93.  
  94.     if (itsResult != noErr)
  95.         return (itsResult);
  96.         
  97.                         // Check for virtual connections stored in a resource.
  98.     GetPortName(theName);
  99.     rezPortInfoH = (MIDIPortInfoHdl) GetResource(theResType, theResID);
  100.     if ( (rezPortInfoH) && (GetHandleSize((Handle) rezPortInfoH) > 0) )
  101.     {
  102.         HLock((Handle) rezPortInfoH);
  103.         ourPortInfoH = GetPortInfo();
  104.         if ((**ourPortInfoH).type == (**rezPortInfoH).type)    // Is this resource a time port?
  105.         {
  106.             if ((**rezPortInfoH).timeBase.clientID != noClient)    // Were we supposed to be synchronized
  107.             {                                        // to another client?
  108.                 theErr = MIDIConnectTime(
  109.                             (**rezPortInfoH).timeBase.clientID,     // Yes, make that client our time base
  110.                             (**rezPortInfoH).timeBase.portID,
  111.                             gSignature,
  112.                             itsPortID);
  113.                 if (theErr != midiVConnectErr)        // Is client still signed in?
  114.                     SetExternalSync();
  115.             }
  116.  
  117. // Were we someone else's time base?  Ch
  118.  
  119.             for (i = 0; i < (**rezPortInfoH).numConnects; i++)
  120.             {
  121.                 theErr = MIDIConnectTime(gSignature, // We are the time base for them
  122.                             itsPortID,
  123.                             (**rezPortInfoH).cList[i].clientID,
  124.                             (**rezPortInfoH).cList[i].portID);
  125.                 if (theErr) break;
  126.             }
  127.         }
  128.         HUnlock((Handle) rezPortInfoH);
  129.         ReleaseResource((Handle) rezPortInfoH);
  130.     }
  131.     return (theErr);
  132. }
  133.  
  134. //--- CMIDITimePort::UpdateSync ---------------------------------------
  135. // Set internal or external time base synchronization depending on
  136. // current connections.  It returns the current synchronization setting
  137. // (same as GetSync).
  138. //--------------------------------------------------------------------
  139.  
  140. short CMIDITimePort::UpdateSync(void)
  141. {
  142.     MIDIPortInfoHdl        thePortInfoH;
  143.     register short        theResult;
  144.  
  145.     thePortInfoH = GetPortInfo();
  146.  
  147.     if (thePortInfoH)
  148.     {
  149.         theResult = GetSync();
  150.         if ( (**thePortInfoH).timeBase.clientID != noClient )
  151.         {
  152.             if (theResult != midiExternalSync)
  153.                 SetExternalSync();
  154.         }
  155.         else
  156.         {
  157.             if (theResult != midiInternalSync)
  158.                 SetInternalSync();
  159.         }
  160.         DisposHandle(thePortInfoH);
  161.     }
  162.     return (itsVersion ? MIDIGetSync(itsRefNum) : -1);
  163. }
  164.  
  165.  
  166. //--- CMIDITimePort:: trivial methods --------------------------
  167.  
  168. short CMIDITimePort::GetSync(void)
  169. {
  170.     return(itsVersion ? MIDIGetSync(itsRefNum) : -1);
  171. }
  172.  
  173. void CMIDITimePort::SetExternalSync(void)
  174. {
  175.     if (itsVersion)
  176.         MIDISetSync(itsRefNum, midiExternalSync);
  177. }
  178.  
  179. void CMIDITimePort::SetInternalSync(void)
  180. {
  181.     if (itsVersion)
  182.         MIDISetSync(itsRefNum, midiInternalSync);
  183. }
  184.  
  185. long CMIDITimePort::GetCurTime(void)
  186. {
  187.     return(itsVersion ? MIDIGetCurTime(itsRefNum) : 0);
  188. }
  189.  
  190. void CMIDITimePort::SetCurTime(long theTime)
  191. {
  192.     if (itsVersion)
  193.         MIDISetCurTime(itsRefNum, theTime);
  194. }
  195.  
  196. void CMIDITimePort::StartTime(void)
  197. {
  198.     if (itsVersion)
  199.         MIDIStartTime(itsRefNum);
  200. }
  201.  
  202. void CMIDITimePort::StopTime(void)
  203. {
  204.     if (itsVersion)
  205.         MIDIStopTime(itsRefNum);
  206. }
  207.  
  208. long CMIDITimePort::GetOffsetTime(void)
  209. {
  210.     return (itsVersion ? MIDIGetOffsetTime(itsRefNum) : 0);
  211. }
  212.  
  213. void CMIDITimePort::SetOffsetTime(long theOffset)
  214. {
  215.     if (itsVersion)
  216.         MIDISetOffsetTime(itsRefNum, theOffset);
  217. }
  218.  
  219. void CMIDITimePort::WakeUp(long theBaseTime, long thePeriod, ProcPtr theTimeProc)
  220. {
  221.     if (itsVersion)
  222.         MIDIWakeUp(itsRefNum, theBaseTime, thePeriod, theTimeProc);
  223. }
  224.  
  225. //--- CMIDITimePort::Perform --------------------------------------
  226. // This turns the time port into a CChore, so that you can call
  227. // gApplication->AssignIdleChore() with this object.
  228. //-----------------------------------------------------------------
  229.  
  230. void CMIDITimePort::Perform(long * maxSleep)
  231. {
  232.     if ( gMIDIClient->WorldChanged() )
  233.         UpdateSync();
  234. }
  235.  
  236. //--- CMIDITimePort::SetConnection --------------------------------
  237. // This sets the connection procedure. Note that for pre-2.0 or
  238. // a NULL connectionProc, the previous method, Perform(), will
  239. // called at idle time, checking for a change in the wind.
  240. //-----------------------------------------------------------------
  241.  
  242. void CMIDITimePort::SetConnection(ProcPtr theConnectionProc)
  243. {
  244.     if ((gMIDIClient->GetShortVerNum() < 0x200 )        // If pre-2.0
  245.         || (theConnectionProc == NULL) )                // or a null pointer
  246.         gApplication->AssignIdleChore( (CChore *) this );
  247.     else                                                // else use connection proc
  248.         SetConnectionProc(theConnectionProc, GetRefCon());
  249. }
  250.  
  251. // end of CMIDITimePort.c
  252.